home *** CD-ROM | disk | FTP | other *** search
/ Windows 95 API Bible / Windows 95 API Bible 3 Disc Set.iso / Win32 API Bible Book 2 of 3.iso / chapter9 / header.c < prev    next >
C/C++ Source or Header  |  1996-03-06  |  12KB  |  380 lines

  1.  
  2. #include <windows.h>  
  3. #include <commctrl.h>
  4. #include "header.h"  
  5.  
  6.  
  7. #if defined (WIN32)
  8.     #define IS_WIN32 TRUE
  9. #else
  10.     #define IS_WIN32 FALSE
  11. #endif
  12.  
  13. #define IS_NT      IS_WIN32 && (BOOL)(GetVersion() < 0x80000000)
  14. #define IS_WIN32S  IS_WIN32 && (BOOL)(!(IS_NT) && (LOBYTE(LOWORD(GetVersion()))<4))
  15. #define IS_WIN95   (BOOL)(!(IS_NT) && !(IS_WIN32S)) && IS_WIN32
  16.  
  17. HINSTANCE hInst;   // current instance
  18.  
  19. LPCTSTR lpszAppName = "MyApp";
  20. LPCTSTR lpszTitle   = "Header Control"; 
  21.  
  22.  
  23. BOOL RegisterWin95( CONST WNDCLASS* lpwc );
  24.  
  25.  
  26. int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
  27.                       LPTSTR lpCmdLine, int nCmdShow)
  28. {
  29.    MSG      msg;
  30.    HWND     hWnd; 
  31.    WNDCLASS wc;
  32.  
  33.    wc.style         = CS_HREDRAW | CS_VREDRAW;
  34.    wc.lpfnWndProc   = (WNDPROC)WndProc;       
  35.    wc.cbClsExtra    = 0;                      
  36.    wc.cbWndExtra    = 0;                      
  37.    wc.hInstance     = hInstance;              
  38.    wc.hIcon         = LoadIcon (hInstance, lpszAppName); 
  39.    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
  40.    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  41.    wc.lpszMenuName  = lpszAppName;              
  42.    wc.lpszClassName = lpszAppName;              
  43.  
  44.    if ( IS_WIN95 )
  45.    {
  46.       if ( !RegisterWin95( &wc ) )
  47.          return( FALSE );
  48.    }
  49.    else if ( !RegisterClass( &wc ) )
  50.       return( FALSE );
  51.  
  52.    hInst = hInstance; 
  53.  
  54.    hWnd = CreateWindow( lpszAppName, 
  55.                         lpszTitle,    
  56.                         WS_OVERLAPPEDWINDOW, 
  57.                         CW_USEDEFAULT, 0, 
  58.                         CW_USEDEFAULT, 0,  
  59.                         NULL,              
  60.                         NULL,              
  61.                         hInstance,         
  62.                         NULL               
  63.                       );
  64.  
  65.    if ( !hWnd ) 
  66.       return( FALSE );
  67.  
  68.    ShowWindow( hWnd, nCmdShow ); 
  69.    UpdateWindow( hWnd );         
  70.  
  71.    while( GetMessage( &msg, NULL, 0, 0) )   
  72.    {
  73.       TranslateMessage( &msg ); 
  74.       DispatchMessage( &msg );  
  75.    }
  76.  
  77.    return( msg.wParam ); 
  78. }
  79.  
  80.  
  81. BOOL RegisterWin95( CONST WNDCLASS* lpwc )
  82. {
  83.    WNDCLASSEX wcex;
  84.  
  85.    wcex.style         = lpwc->style;
  86.    wcex.lpfnWndProc   = lpwc->lpfnWndProc;
  87.    wcex.cbClsExtra    = lpwc->cbClsExtra;
  88.    wcex.cbWndExtra    = lpwc->cbWndExtra;
  89.    wcex.hInstance     = lpwc->hInstance;
  90.    wcex.hIcon         = lpwc->hIcon;
  91.    wcex.hCursor       = lpwc->hCursor;
  92.    wcex.hbrBackground = lpwc->hbrBackground;
  93.    wcex.lpszMenuName  = lpwc->lpszMenuName;
  94.    wcex.lpszClassName = lpwc->lpszClassName;
  95.  
  96.    // Added elements for Windows 95.
  97.    //...............................
  98.    wcex.cbSize = sizeof(WNDCLASSEX);
  99.    wcex.hIconSm = LoadImage(wcex.hInstance, lpwc->lpszClassName, 
  100.                             IMAGE_ICON, 16, 16,
  101.                             LR_DEFAULTCOLOR );
  102.             
  103.    return RegisterClassEx( &wcex );
  104. }
  105.  
  106. LPCTSTR pszTitles[] = { "Name", "Type", "Size" };
  107.  
  108. int GetColumnOffs( HWND hHeader, int nColNum )
  109. {
  110.    HD_ITEM hi;
  111.    int     i;
  112.    int     x = 0;
  113.  
  114.    hi.mask = HDI_WIDTH;
  115.  
  116.    // Calculate the column position.
  117.    //...............................
  118.    for( i=0; i<nColNum; i++ )
  119.    {
  120.       Header_GetItem( hHeader, i, &hi );
  121.       x += hi.cxy;
  122.    }
  123.  
  124.    return( x );
  125. }
  126.  
  127. LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
  128. {
  129. static HD_LAYOUT hl;
  130. static WINDOWPOS wp;
  131. static RECT      rc;
  132. static HDC       hdc;
  133. static int       nCurItem;
  134. static HWND      hHeader = NULL;
  135.  
  136.    switch( uMsg )
  137.    {
  138.       case WM_CREATE :
  139.               InitCommonControls();
  140.  
  141.               // Create the header control.
  142.               //...........................
  143.               hHeader = CreateWindowEx( 0, WC_HEADER, "",
  144.                                         WS_CHILD | WS_VISIBLE |
  145.                                         HDS_BUTTONS,
  146.                                         0, 0, 10, 10, hWnd, 
  147.                                         (HMENU)1, hInst, NULL );
  148.  
  149.               // Initialize the HD_LAYOUT members.
  150.               //..................................
  151.               hl.pwpos = ℘
  152.               hl.prc   = &rc;
  153.  
  154.               if ( hHeader )
  155.               {
  156.                  HD_ITEM hi;
  157.                  int     i;
  158.  
  159.                  SendMessage( hHeader, WM_SETFONT, 
  160.                               (WPARAM)GetStockObject( DEFAULT_GUI_FONT ), 0 );
  161.  
  162.                  for( i=0; i<3; i++ )
  163.                  {
  164.                     hi.mask    = HDI_FORMAT | HDI_TEXT | HDI_WIDTH;
  165.                     hi.pszText = (LPTSTR)pszTitles[i];
  166.                     hi.fmt     = HDF_STRING;
  167.                     hi.cxy     = 100;
  168.  
  169.                     Header_InsertItem( hHeader, i, (LPARAM)&hi ); 
  170.                  }
  171.               }
  172.               break;
  173.  
  174.       case WM_SIZE :
  175.               rc.top    = 0;
  176.               rc.left   = 0;
  177.               rc.right  = LOWORD( lParam );
  178.               rc.bottom = HIWORD( lParam );
  179.  
  180.               Header_Layout( hHeader, &hl );
  181.               SetWindowPos( hHeader, hWnd, wp.x, wp.y, wp.cx, wp.cy, wp.flags ); 
  182.               break;
  183.  
  184.       case WM_CONTEXTMENU :
  185.               {
  186.                  HD_HITTESTINFO hi;
  187.  
  188.                  hi.pt.x = LOWORD( lParam );
  189.                  hi.pt.y = HIWORD( lParam );
  190.  
  191.                  // Convert the coordinates to client.
  192.                  //...................................
  193.                  ScreenToClient( hHeader, &hi.pt );
  194.  
  195.                  // Test for a hit.
  196.                  //................
  197.                  SendMessage( hHeader, HDM_HITTEST, 0, (LPARAM)&hi );
  198.  
  199.                  // If a hit occurred, display menu.
  200.                  //.................................                 
  201.                  if ( hi.flags & HHT_ONHEADER )
  202.                  {
  203.                     HD_ITEM hdi;
  204.                     HMENU   hMenu = CreatePopupMenu();
  205.  
  206.                     // Retrieve the current format.
  207.                     //.............................
  208.                     hdi.mask = HDI_FORMAT;
  209.                     Header_GetItem( hHeader, hi.iItem, &hdi );
  210.  
  211.                     nCurItem = hi.iItem;
  212.  
  213.                     // Build the menu and display it.
  214.                     //...............................
  215.                     AppendMenu( hMenu, MF_STRING, IDM_LEFT, "&Left" );
  216.                     AppendMenu( hMenu, MF_STRING, IDM_CENTER, "&Center" );
  217.                     AppendMenu( hMenu, MF_STRING, IDM_RIGHT, "&Right" );
  218.  
  219.                     CheckMenuRadioItem( hMenu, IDM_LEFT, IDM_RIGHT,
  220.                            (hdi.fmt & HDF_JUSTIFYMASK) == HDF_LEFT ? IDM_LEFT :
  221.                            (hdi.fmt & HDF_JUSTIFYMASK) == HDF_CENTER ? IDM_CENTER :
  222.                            IDM_RIGHT, MF_BYCOMMAND );
  223.  
  224.                     TrackPopupMenu( hMenu, TPM_LEFTALIGN | TPM_LEFTBUTTON |
  225.                                               TPM_RIGHTBUTTON,
  226.                                               LOWORD( lParam ), HIWORD( lParam ),
  227.                                               0, hWnd, NULL );
  228.                     DestroyMenu( hMenu );
  229.                  }
  230.               }
  231.               break;
  232.  
  233.       case WM_NOTIFY :
  234.               {
  235.                  int        x;
  236.                  HD_NOTIFY* pHN = (HD_NOTIFY*)lParam;
  237.  
  238.                  switch( pHN->hdr.code )
  239.                  {
  240.                     case HDN_BEGINTRACK :
  241.                          // Only allow Left Mouse Drag.
  242.                          //............................
  243.                          if ( pHN->iButton != 0 )
  244.                             return( TRUE );
  245.  
  246.                          // Get the column offset.
  247.                          //.......................
  248.                          x = GetColumnOffs( hHeader, pHN->iItem ) +
  249.                                 pHN->pitem->cxy;
  250.  
  251.                          GetClientRect( hWnd, &rc );
  252.  
  253.                          // Fix up rect for the invert.
  254.                          //............................
  255.                          rc.left   = x;
  256.                          rc.top    = wp.cy;
  257.                          rc.right  = x+1;
  258.  
  259.                          // Get the window DC and invert the rect.
  260.                          //.......................................
  261.                          hdc = GetDC( hWnd );
  262.                          InvertRect( hdc, &rc );
  263.  
  264.                          break;
  265.  
  266.                     case HDN_TRACK :
  267.                          // Turn off the invert on the old rect.
  268.                          //.....................................
  269.                          InvertRect( hdc, &rc );
  270.  
  271.                          // Get the column offset.
  272.                          //.......................
  273.                          x = GetColumnOffs( hHeader, pHN->iItem ) +
  274.                                 pHN->pitem->cxy;
  275.  
  276.                          GetClientRect( hWnd, &rc );
  277.  
  278.                          // Invert the new rect.
  279.                          //.....................
  280.                          rc.left   = x;
  281.                          rc.top    = wp.cy;
  282.                          rc.right  = x+1;
  283.                          InvertRect( hdc, &rc );
  284.                          break;
  285.  
  286.                     case HDN_ENDTRACK :
  287.                          // Turn off the invert and release the DC.
  288.                          //........................................
  289.                          InvertRect( hdc, &rc );
  290.                          ReleaseDC( hWnd, hdc );
  291.                          break;
  292.  
  293.                     case HDN_ITEMCHANGING :
  294.                          // Do not allow the first column to be changed.
  295.                          //.............................................
  296.                          if ( pHN->iItem == 0 )
  297.                             return( TRUE );
  298.  
  299.                          break;
  300.  
  301.                     case HDN_ITEMCHANGED :
  302.                          // Update the contents of the window to reflect
  303.                          // the new column alignment.
  304.                          //.............................................
  305.                          break;
  306.  
  307.                     case HDN_ITEMCLICK :
  308.                          // Sort the column's contents
  309.                          //...........................
  310.                          break;
  311.                  }
  312.               }
  313.               break;
  314.  
  315.       case WM_COMMAND :
  316.               switch( LOWORD( wParam ) )
  317.               {
  318.                  case IDM_LEFT :
  319.                  case IDM_RIGHT :
  320.                  case IDM_CENTER :
  321.                         {
  322.                            HD_ITEM hdi;
  323.  
  324.                            // Update the alignment of the column.
  325.                            //....................................
  326.                            hdi.mask = HDI_FORMAT;
  327.                            hdi.fmt  = HDF_STRING + 
  328.                                 ( LOWORD( wParam ) == IDM_LEFT ? HDF_LEFT :
  329.                                   LOWORD( wParam ) == IDM_CENTER ? HDF_CENTER :
  330.                                   HDF_RIGHT );
  331.  
  332.                            Header_SetItem( hHeader, nCurItem, &hdi );
  333.                         }
  334.                         break;
  335.  
  336.                  case IDM_ABOUT :
  337.                         DialogBox( hInst, "AboutBox", hWnd, (DLGPROC)About );
  338.                         break;
  339.  
  340.                  case IDM_EXIT :
  341.                         DestroyWindow( hWnd );
  342.                         break;
  343.               }
  344.               break;
  345.       
  346.       case WM_DESTROY :
  347.               PostQuitMessage(0);
  348.               break;
  349.  
  350.       default :
  351.             return( DefWindowProc( hWnd, uMsg, wParam, lParam ) );
  352.    }
  353.  
  354.    return( 0L );
  355. }
  356.  
  357.  
  358. LRESULT CALLBACK About( HWND hDlg,           
  359.                         UINT message,        
  360.                         WPARAM wParam,       
  361.                         LPARAM lParam)
  362. {
  363.    switch (message) 
  364.    {
  365.        case WM_INITDIALOG: 
  366.                return (TRUE);
  367.  
  368.        case WM_COMMAND:                              
  369.                if (   LOWORD(wParam) == IDOK         
  370.                    || LOWORD(wParam) == IDCANCEL)    
  371.                {
  372.                        EndDialog(hDlg, TRUE);        
  373.                        return (TRUE);
  374.                }
  375.                break;
  376.    }
  377.  
  378.    return (FALSE); 
  379. }
  380.